#include "mqtt.h"


StaticJsonDocument<200> json_doc,json_rep;//json对象

long lastReconnectAttempt = 0;

bool debug = false;

boolean reconnect() {
Serial.println("mqtt connceting server.");
if (mqtt_client.connect(host_name,account,passwd)) {
    Serial.println("mqtt connceted server.");
    mqtt_client.subscribe(mqtt_sub_topic,1);
// Once connected, publish an announcement...
// mqtt_client.publish("outTopic","hello world");
// ... and resubscribe
// mqtt_client.subscribe("inTopic");
}
return mqtt_client.connected();
}

void callback(char* topic, byte* payload, unsigned int length) {
    Serial.print("Message arrived [");
    Serial.print(topic);   // 打印主题信息
    Serial.print("] ");
    for (int i = 0; i < length; i++) 
    {
        Serial.print((char)payload[i]); // 打印主题内容
    }
    Serial.println();
    DeserializationError error = deserializeJson(json_doc,payload); 

    if(!error)
    {
        if(!((String)topic).compareTo(mqtt_sub_topic))
            {
            if(json_doc["ac"]=="open1")
            {
                if(work_state==0){
                    work_state=json_doc["io"];
                    if(debug == true){
                        if(work_state==1){
                            digitalWrite(KEY1,HIGH);
                            delay(200);
                            digitalWrite(KEY1,LOW);
                            work_state = 0;
                        }
                        if(work_state==2){
                            digitalWrite(KEY3,HIGH);
                            delay(200);
                            digitalWrite(KEY3,LOW);
                            work_state = 0;
                        }
                        if(work_state==3){
                            digitalWrite(KEY2,HIGH);
                            delay(200);
                            digitalWrite(KEY2,LOW);
                            work_state = 0;
                        }
                        if(work_state==4){
                            digitalWrite(KEY5,HIGH);
                            delay(200);
                            digitalWrite(KEY5,LOW);
                            work_state = 0;
                        }
                        if(work_state==5){
                            digitalWrite(KEY6,HIGH);
                            delay(200);
                            digitalWrite(KEY6,LOW);
                            work_state = 0;
                        }
                        if(work_state==6){
                            digitalWrite(KEY4,HIGH);
                            delay(200);
                            digitalWrite(KEY4,LOW);
                            work_state = 0;
                        }
                        
                    }
                    if(work_state == 24 && machine_type == 2){
                        work_state = 1;
                    }                //新机器io1是美式，将旧机器io24映射到新机器io
                    if(work_state==9){
                        mqtt_jzz=json_doc["jzz1"];
                    }
                    else if(work_state==11){
                        mqtt_jzz=json_doc["jzz2"];
                    }
                    else if(work_state==18){
                        natie_time=json_doc["nt_time"];
                    }
                    else if(work_state==19){
                        kabuqinuo_time=json_doc["kb_time"];
                    }
                    else if(work_state==20){
                        yishi_time=json_doc["yi_time"];
                    }
                    else if(work_state==21){
                        clean_time=json_doc["wash_time"];
                    }
                    else if(work_state==22){
                        yeru_pluse=json_doc["ye_num"];
                    }
                    else if(work_state==23){
                        work_times=json_doc["sum_num"];
                        pref.begin("config");
                        pref.putUInt("work_times",work_times);
                        pref.end();
                        // Serial.printf("sum_num %d\n",work_times);
                    }
                    else if(work_state==25){
                        json_rep.clear();
                        json_rep["io"]="25";
                        json_rep["num"]=work_times;
                        char state_doc[measureJson(json_rep) + 1];
                        serializeJson(json_rep, state_doc, measureJson(json_rep) + 1);
                        mqtt_client.publish(mqtt_pub_topic,state_doc);
                        // work_times=json_doc["sum_num"];
                        // Serial.printf("sum_num %d\n",work_times);
                    }
                    else if(work_state==27){
                        channel1_pluse=json_doc["cha1_num"];
                        pref.begin("config");
                        pref.putUInt("channel1_pluse",channel1_pluse);
                        pref.end();
                    }
                    else if(work_state==28){
                        json_rep.clear();
                        json_rep["io"]="28";
                        json_rep["num"]=channel1_pluse;
                        char state_doc[measureJson(json_rep) + 1];
                        serializeJson(json_rep, state_doc, measureJson(json_rep) + 1);
                        mqtt_client.publish(mqtt_pub_topic,state_doc);
                        // work_times=json_doc["sum_num"];
                        // Serial.printf("sum_num %d\n",work_times);
                    }
                    else if(work_state==29){
                        bee_interve1 = json_doc["buz1"];
                        bee_interve2 = json_doc["buz2"];
                        pref.begin("config");
                        pref.putUInt("bee_interve1",bee_interve1);
                        pref.putUInt("bee_interve2",bee_interve2);
                        pref.end();
                    }
                    else if(work_state==30){
                        json_rep.clear();
                        json_rep["io"]="30";
                        json_rep["buz1"]=bee_interve1;
                        json_rep["buz2"]=bee_interve2;
                        char state_doc[measureJson(json_rep) + 1];
                        serializeJson(json_rep, state_doc, measureJson(json_rep) + 1);
                        mqtt_client.publish(mqtt_pub_topic,state_doc);
                        // work_times=json_doc["sum_num"];
                        // Serial.printf("sum_num %d\n",work_times);
                    }
                    else if(work_state==31){
                        machine_type = json_doc["type"];
                        pref.begin("config");
                        pref.putUInt("machine_type",machine_type);
                        pref.end();
                    }
                    else if(work_state==32){
                        json_rep.clear();
                        json_rep["io"]="32";
                        json_rep["type"]=machine_type;
                        char state_doc[measureJson(json_rep) + 1];
                        serializeJson(json_rep, state_doc, measureJson(json_rep) + 1);
                        mqtt_client.publish(mqtt_pub_topic,state_doc);
                        // work_times=json_doc["sum_num"];
                        // Serial.printf("sum_num %d\n",work_times);
                    }
                    else if(work_state==33){
                        debug = true;
                        json_rep.clear();
                        json_rep["io"]="33";
                        json_rep["debug"]=true;
                        char state_doc[measureJson(json_rep) + 1];
                        serializeJson(json_rep, state_doc, measureJson(json_rep) + 1);
                        mqtt_client.publish(mqtt_pub_topic,state_doc);
                    }
                    else if(work_state==34){
                        debug = false;
                        json_rep.clear();
                        json_rep["io"]="34";
                        json_rep["debug"]=false;
                        char state_doc[measureJson(json_rep) + 1];
                        serializeJson(json_rep, state_doc, measureJson(json_rep) + 1);
                        mqtt_client.publish(mqtt_pub_topic,state_doc);
                        // work_times=json_doc["sum_num"];
                        // Serial.printf("sum_num %d\n",work_times);
                    }
                    json_rep.clear();
                    json_rep["state"]="ok";
                    json_rep["io"]=work_state;
                    char state_doc[measureJson(json_rep) + 1];
                    serializeJson(json_rep, state_doc, measureJson(json_rep) + 1);
                    mqtt_client.publish(mqtt_pub_topic,state_doc);
                }
                else{
                    Serial.printf("busy.....\n");
                    json_rep.clear();
                    json_rep["state"]="busy";
                    json_rep["io"]=work_state;
                    char state_doc[measureJson(json_rep) + 1];
                    serializeJson(json_rep, state_doc, measureJson(json_rep) + 1);
                    mqtt_client.publish(mqtt_pub_topic,state_doc);
                }
            }
            }
    }
}

void mqtt_loop(void *pvParameters)
{
while(1)
{
if (!mqtt_client.connected()) {
WIFI_connect();                                                    //函数会判断wifi是否连接，若是wifi断开会执行到wifi重连再返回，否则直接返回
long now = millis();
if (now - lastReconnectAttempt > 5000) {
    lastReconnectAttempt = now;
    // Attempt to reconnect
    if (reconnect()) {
    lastReconnectAttempt = 0;
    }
}
} else {
// Client connected
//上电第一次连上mqtt发送当前工作次数
if(pub_state==0){
    json_rep.clear();
    json_rep["type"]="num";
    json_rep["value"]=work_times;
    char state_doc[measureJson(json_rep) + 1];
    serializeJson(json_rep, state_doc, measureJson(json_rep) + 1);
    mqtt_client.publish(mqtt_pub_topic,state_doc);
    pub_state=1;
}
mqtt_client.loop();
}

delay(1000);
}
}

void mqtt_init(void)
{
    strcpy(account,mac);
    sprintf(mqtt_sub_topic,"/c/%s/get",mac);
    sprintf(mqtt_pub_topic,"/c/%s/send",mac);
    mqtt_client.setClient(wifi_client);
    mqtt_client.setServer(mqtt_server.c_str(), mqtt_port);                              //设定MQTT服务器与使用的端口，1883是默认的MQTT端口
    mqtt_client.setCallback(callback);                                          //设定回调方式，当ESP8266收到订阅消息时会调用此方法

}

int mqtt_log(const char *format, ...) {
    char loc_buf[64];
    char *temp = loc_buf;
    va_list arg;
    va_list copy;
    va_start(arg, format);
    va_copy(copy, arg);
    
    // 计算格式化字符串长度
    int len = vsnprintf(temp, sizeof(loc_buf), format, copy);
    va_end(copy);
    
    if(len < 0) {
        va_end(arg);
        return 0;
    }
    
    // 如果缓冲区不够大，重新分配内存
    if(len >= (int)sizeof(loc_buf)) {
        temp = (char*)malloc(len + 1);
        if(temp == NULL) {
            va_end(arg);
            return 0;
        }
        len = vsnprintf(temp, len + 1, format, arg);
    }
    va_end(arg);
    
    // 通过MQTT发送日志
    json_rep.clear();
    json_rep["type"] = "log";
    json_rep["msg"] = temp;
    
    char state_doc[measureJson(json_rep) + 1];
    serializeJson(json_rep, state_doc, measureJson(json_rep) + 1);
    mqtt_client.publish(mqtt_pub_topic, state_doc);
    
    if(temp != loc_buf) {
        free(temp);
    }
    
    return len;
}